package com.org.msmvc.sys.service.impl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.org.msmvc.sys.dao.common.Entity;
import com.org.msmvc.sys.dao.common.EntityMapper;
import com.org.msmvc.sys.dao.common.EntityUtil;
import com.org.msmvc.sys.dao.common.InputData;
import com.org.msmvc.sys.dao.common.SearchCondition;
import com.org.msmvc.sys.service.EntityService;
/*
 * 通用数据服务实现，单个表的数据查询、新建、修改、删除
 * 参数见接口说明
 * 赵光 climber@pku.org.cn
 */
@Service("entityService")
public class EntityServiceImpl implements EntityService{
	private Log log=LogFactory.getLog(this.getClass());
	//使用mybatis配置
	@Autowired
	private EntityMapper entityMapper;
	@Autowired
	private EntityMapper EntityMapperNoCache;
	
	//查询
	@SuppressWarnings("rawtypes")
	public List<Map<String, Object>> list(Object entity,String queryCondition,int page,int rows,String sort,String order,String fields) throws Exception {
			//1、构造条件
			SearchCondition condition =new SearchCondition();
			condition.setTableName(EntityUtil.getTableName(entity));
			if(page>0) condition.setPage(page);
			if(rows>0) condition.setRows(rows);
			condition.setOrder(order);
			condition.setSort(sort);
			condition.setFields(fields);
			//2、构造查询条件
			if(queryCondition!=null && queryCondition.length()>0){
				condition.setQueryCondition(queryCondition);
			}
			//3、执行 取得数据列表
			List<Map<String, Object>> data;
			/*if(entity instanceof EntityNoCache){
				data= EntityMapperNoCache.list(condition);
			}else{
				data= entityMapper.list(condition);
			}*/
			data= entityMapper.list(condition);
			//4、取得Entity类型的属性的名称
			Map<String,Field> entityFields;
			if(fields==null){
				entityFields=EntityUtil.getEntityFields(entity, null);
			}else{
				entityFields=EntityUtil.getEntityFields(entity, condition.getShowFields());
			}
			
			for (Map<String, Object> row : data) {
				for (String key : row.keySet()) {
					if (!"id".equals(key)) {
						// 如果是Entity类型
						if (entityFields.containsKey(key)) {
							Object value = row.get(key);
							if (value != null) {
								try {
									int id = Integer.parseInt(value + "");
									if (id > 0) {
										Class clazz = entityFields.get(key).getType();
										String fullName = clazz.getName();
										String tableName = "jtx_"+ fullName.substring(fullName.lastIndexOf(".") + 1);
										condition = new SearchCondition();
										condition.setTableName(tableName);
										condition.setPage(1);
										condition.setRows(1);
										condition.setFields("name");
										condition.setQueryCondition("id=" + id);
										List<Map<String, Object>> d = entityMapper.list(condition);
										if (d.size() > 0) {
											Map<String, Object> newValue = d.get(0);
											newValue.put("id", id);
											row.put(key, newValue);
										}
									}
								} catch (SecurityException e) {
									log.error(e.getMessage());
								}catch (NumberFormatException e) {
									//id非整数，有可能是对象已经有了;
								}catch (Exception e) {
									//可能是没有name属性
									log.error(e.getMessage());
								}
							}
						}
					 }
				 }
			}
			return data;
		//}
	}
	//取得实体列表，输入参数同list，输出已经将map集合转换为对象了，便于在服务端使用。如果直接返回给客户端，建议使用list。
	public List<Object> listBean(Object entity,String queryCondition,int page,int rows,String sort,String order,String fields) throws Exception {
		List<Map<String, Object>> rs=this.list(entity, queryCondition, page, rows, sort, order, fields);
		//将map集合转换为对象
		List<Object> entities = new ArrayList<Object>();
		for(Map<String, Object> row:rs){
			try {
				Object aEntity = entity.getClass().newInstance();
				this.setEntityValue(aEntity, row);
				entities.add(aEntity);
			} catch (InstantiationException e) {
				log.error(e.getMessage());
			} catch (IllegalAccessException e) {
				log.error(e.getMessage());
			}
		}
		return entities;
	}
	//取得符合条件的数据总数
	public int getTotal(Object entity,String queryCondition) throws Exception{
			//1、构造条件
			SearchCondition condition =new SearchCondition();
			condition.setTableName(EntityUtil.getTableName(entity));
			//2、构造查询条件
			if(queryCondition!=null && queryCondition.length()>0){
				condition.setQueryCondition(queryCondition);
			}
			//3、执行 取得数据总数
			return entityMapper.getTotal(condition);
	}
	//插入修改一个对象
	public int[] update(Object entities[],List<String> fields[]) throws Exception {
			int[] rs=new int[entities.length];
			//执行
			int i=0;
			for(Object entity:entities){
				rs[i]=this.update(entity, fields[i]);
				i++;
			}		
			return rs;
		//}
	}
	//插入修改一个对象
	public int update(Object entity,List<String> fields) throws Exception {
			//执行
			String tableName=EntityUtil.getTableName(entity);
			InputData input = new InputData(tableName);
			//要去掉Id后的属性表
			fields.remove("id");
			input.setFields(fields);
			//读取数据值对象
			List<Object> values = new ArrayList<Object>();
			for(String fieldName:fields){
				Object v = EntityUtil.getValue(entity, fieldName);
				values.add(v);
			}
			input.setValues(values);
			int id= EntityUtil.getId(entity);
			input.setId(id);
			try{
				//执行
				if(id>0){
					//修改一条数据
					entityMapper.update(input);
				}else{
					//新建一条数据
					entityMapper.insert(input);			
					id=input.getId();
				}
			}catch(Exception e){
				if(e.getMessage().indexOf("Duplicate entry")>-1){
					throw new Exception("系统检测到违反唯一性约束");
				}else{
					throw new Exception(e.getMessage());
				}
			}
			return id;
		//}
	}
	//删除
	public void delete(Object entity,int id) throws Exception {
			//构造条件
			InputData input = new InputData(EntityUtil.getTableName(entity));
			input.setId(id);
			//执行删除
			entityMapper.delete(input);		
	}
	public Map<String, Object> getEntity(Object entity, int id,String fields) throws Exception {		
		List<Map<String, Object>> rs = this.list(entity, "id="+id, 1, 1, "", "", fields);
		if(rs.size()>0){
			return rs.get(0);
		}else{
			throw new Exception("找不到符合条件的对象");
		}
	}
	public void setEntityValue(Entity entity, int id,String fields) throws Exception {
		//取得属性值Map集合
		Map<String, Object> row = this.getEntity(entity, id, fields);
		entity.setId(id);
		this.setEntityValue(entity, row);
	}
	//将map集合转换为一个对象
	@SuppressWarnings("unchecked")
	private void setEntityValue(Object entity,Map<String, Object> row) throws Exception {
		//取得全部的对象类型的属性，后面要用
		Map<String,Field> entityFields=EntityUtil.getEntityFields(entity, row.keySet());
		//将Map集合的值赋值到对象属性中
		for (String key : row.keySet()) {
			Object value = row.get(key);
			//value如果是map集合，表示是一个对象
			if(value instanceof Map){
				Class<?> entityClass = entityFields.get(key).getType();
				try {
					//创建一个属性对象
					Entity entityValue = (Entity)entityClass.newInstance();
					Map<String, Object> mapValue = (Map<String, Object>)value;
					//设置id
					int entityId=(Integer)mapValue.get("id");
					entityValue.setId(entityId);
					//设置名称
					String entityName=(String)mapValue.get("name");
					entityValue.setName(entityName);
					//将新的属性对象赋值给当前对象
					EntityUtil.setValue(entity, key, entityValue);
				} catch (InstantiationException e) {
					log.error(e.getMessage());
				} catch (IllegalAccessException e) {
					log.info(e.getMessage());
				}
			}else{
				EntityUtil.setValue(entity, key, value);
			}
		}
	}
    //清除缓存
	public void clearCache() {
		entityMapper.clearCache();
	}
}
